/*! \file mem_allocator.h
 *	\brief This class is ALWAYS needed to avoid difference in typeid of types for different configs
 *
 *	created:	2009/11/20
 *	created:	20:11:2009   18:34
 *	filename: 	o:\main\libs\mem\mem_allocator.h
 *	file path:	o:\main\libs\mem
 *	file base:	mem_allocator
 *	file ext:	h
 *	author:		Vitalii Trubchaninov
 *				venngraydog@gmail.com
 */

#ifndef _MEM_MEM_ALLOCATOR_H_
#define _MEM_MEM_ALLOCATOR_H_

#pragma once

#include "defs.h"

#if TT_MEM_ENABLED
#include <tbb/scalable_allocator.h>
#else
#include <memory>
#endif //TT_MEM_ENABLED

namespace tt{
namespace mem{

namespace impl{
class BlockInfo;
} //namespace impl

template<class _Ty>
class allocator
{
#if TT_MEM_ENABLED
	typedef tbb::scalable_allocator<_Ty> Allocator;
#else //TT_MEM_ENABLED
	typedef std::allocator<_Ty> Allocator;
#endif //TT_MEM_ENABLED
public:
	typedef _Ty value_type;
	typedef value_type *pointer;
	typedef const value_type *const_pointer;
	typedef value_type& reference;
	typedef const value_type& const_reference;
	typedef size_t size_type;
	typedef ptrdiff_t difference_type;

	template<class _Other>
	struct rebind {
		typedef allocator<_Other> other;
	};

	allocator(); 
	allocator(const allocator<value_type>& _Right);

	template<class Other>
	friend class allocator;

	template<class Other>
	allocator(const allocator<Other>& _Right);

	template<class Other>
	allocator& operator=(const allocator<Other>& _Right);

	pointer address(reference _Val) const;
	const_pointer address(const_reference _Val) const;

	pointer allocate(size_type _Count, const void* _Hint = 0);

	void construct(pointer _Ptr, const value_type& _Val);

	void deallocate(pointer _Ptr, size_type _Count);

	void destroy(pointer _Ptr);

	size_type max_size( ) const;

private:
	Allocator m_allocator;
#if TT_MEM_ENABLED && TT_MEM_PROFILING
	impl::BlockInfo* m_section;
#endif //TT_MEM_ENABLED && TT_MEM_PROFILING
};

//Venn: STLPort needs this definitions for some reason!
template<class _Ty, class _Other>
bool operator==(const allocator<_Ty>&, const allocator<_Other>&);

template<class _Ty, class _Other>
bool operator!=(const allocator<_Ty>&, const allocator<_Other>&);

} //namespace mem
} //namespace tt

#include "mem_allocator.inl"

#endif //_MEM_MEM_ALLOCATOR_H_
